#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@author: liang kang
@contact: gangkanli1219@gmail.com
@time: 2018/5/24 10:49
@desc: 
"""
import itkExtras
import numpy as np

from utils.file.image_io import read_dicom
from utils.functions import check_spacing
from utils.functions import merge_dict


class Seed(object):

    def __init__(self, point=None,
                 parent=None):
        self.point = point
        self.parent = parent


class Roi(object):

    def __init__(self):
        self.id = None
        self.edge_maps = None


class Nodule(object):

    def __init__(self):
        self.patient_id = None
        self.series_id = None
        self.index_id = 0
        self.features = {}
        self.roi_list = []
        self.points = None
        self.diameter = 0
        self.centroid = None

    def get_center(self):
        all_points = np.concatenate([roi.edge_maps for roi in self.roi_list])
        return np.mean(all_points, axis=0)

    def merge_nodule(self, nodule):
        self.features = merge_dict(self.features, nodule.features)


class Image(object):

    def __init__(self, instance=None):
        self.origin = None
        self.spacing = None
        self.index = None
        self.image_array = None
        self.break_scan = False

        self.patient_id = None
        self.series_id = None

        if instance is not None:
            self.origin = instance.origin
            self.spacing = instance.spacing
            self.index = instance.index
            self.patient_id = instance.patient_id
            self.series_id = instance.series_id

    def init_with_itk(self, image):
        self.image_array = itkExtras.GetArrayFromImage(image)
        self.origin = np.array(image.GetOrigin())
        self.spacing = np.array([image.GetSpacing()[0],
                                 image.GetSpacing()[1],
                                 image.GetSpacing()[2]])
        self.index = np.array(image.GetLargestPossibleRegion().GetIndex())

    def init_with_dcm(self, dcm):
        image, dcm_io = read_dicom(dcm)
        self.init_with_itk(image)
        spacing_io = dcm_io.GetValueFromTag('0028|0030', '')[1].split('\\')
        spacing_io.append(dcm_io.GetValueFromTag('0018|0050', '')[1])
        self.series_id = dcm_io.GetValueFromTag('0020|000E', '')[1]
        self.patient_id = dcm_io.GetValueFromTag('0010|0020', '')[1]
        self.spacing = check_spacing(self.spacing, spacing_io)
        if self.spacing is None:
            self.break_scan = True

    def to_itk(self):
        if self.image_array.dtype == np.bool:
            dtype = np.uint8
        else:
            dtype = self.image_array.dtype
        image = itkExtras.GetImageFromArray(self.image_array.astype(dtype))
        image.SetSpacing(self.spacing)
        image.SetOrigin(self.origin)
        if self.index is not None:
            region = image.GetLargestPossibleRegion()
            region.SetIndex(self.index.tolist())
            image.SetRegions(region)
        return image
